home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 002 / emacssrc.arc / FILE.C < prev    next >
C/C++ Source or Header  |  1987-02-02  |  20KB  |  606 lines

  1. /*    FILE.C:   for MicroEMACS
  2.  
  3.     The routines in this file handle the reading, writing
  4.     and lookup of disk files.  All of details about the
  5.     reading and writing of the disk are in "fileio.c".
  6.  
  7. */
  8.  
  9. #include        <stdio.h>
  10. #include    "estruct.h"
  11. #include        "edef.h"
  12.  
  13. #if    MEGAMAX
  14. overlay "file"
  15. #endif
  16.  
  17. /*
  18.  * Read a file into the current
  19.  * buffer. This is really easy; all you do it
  20.  * find the name of the file, and call the standard
  21.  * "read a file into the current buffer" code.
  22.  * Bound to "C-X C-R".
  23.  */
  24. fileread(f, n)
  25. {
  26.         register int    s;
  27.         char fname[NFILEN];
  28.  
  29.     if (restflag)        /* don't allow this command if restricted */
  30.         return(resterr());
  31.         if ((s=mlreply("Read file: ", fname, NFILEN)) != TRUE)
  32.                 return(s);
  33.         return(readin(fname, TRUE));
  34. }
  35.  
  36. /*
  37.  * Insert a file into the current
  38.  * buffer. This is really easy; all you do it
  39.  * find the name of the file, and call the standard
  40.  * "insert a file into the current buffer" code.
  41.  * Bound to "C-X C-I".
  42.  */
  43. insfile(f, n)
  44. {
  45.         register int    s;
  46.         char fname[NFILEN];
  47.  
  48.     if (restflag)        /* don't allow this command if restricted */
  49.         return(resterr());
  50.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  51.         return(rdonly());    /* we are in read only mode    */
  52.         if ((s=mlreply("Insert file: ", fname, NFILEN)) != TRUE)
  53.                 return(s);
  54.         return(ifile(fname));
  55. }
  56.  
  57. /*
  58.  * Select a file for editing.
  59.  * Look around to see if you can find the
  60.  * fine in another buffer; if you can find it
  61.  * just switch to the buffer. If you cannot find
  62.  * the file, create a new buffer, read in the
  63.  * text, and switch to the new buffer.
  64.  * Bound to C-X C-F.
  65.  */
  66. filefind(f, n)
  67. {
  68.         char fname[NFILEN];    /* file user wishes to find */
  69.         register int s;        /* status return */
  70.  
  71.     if (restflag)        /* don't allow this command if restricted */
  72.         return(resterr());
  73.         if ((s=mlreply("Find file: ", fname, NFILEN)) != TRUE)
  74.                 return(s);
  75.     return(getfile(fname, TRUE));
  76. }
  77.  
  78. viewfile(f, n)    /* visit a file in VIEW mode */
  79. {
  80.         char fname[NFILEN];    /* file user wishes to find */
  81.         register int s;        /* status return */
  82.     register WINDOW *wp;    /* scan for windows that need updating */
  83.  
  84.     if (restflag)        /* don't allow this command if restricted */
  85.         return(resterr());
  86.         if ((s=mlreply("View file: ", fname, NFILEN)) != TRUE)
  87.                 return (s);
  88.     s = getfile(fname, FALSE);
  89.     if (s) {    /* if we succeed, put it in view mode */
  90.         curwp->w_bufp->b_mode |= MDVIEW;
  91.  
  92.         /* scan through and update mode lines of all windows */
  93.         wp = wheadp;
  94.         while (wp != NULL) {
  95.             wp->w_flag |= WFMODE;
  96.             wp = wp->w_wndp;
  97.         }
  98.     }
  99.     return(s);
  100. }
  101.  
  102. #if    CRYPT
  103. resetkey()    /* reset the encryption key if needed */
  104.  
  105. {
  106.     register int s;    /* return status */
  107.  
  108.     /* turn off the encryption flag */
  109.     cryptflag = FALSE;
  110.  
  111.     /* if we are in crypt mode */
  112.     if (curbp->b_mode & MDCRYPT) {
  113.         if (curbp->b_key[0] == 0) {
  114.             s = setkey(FALSE, 0);
  115.             if (s != TRUE)
  116.                 return(s);
  117.         }
  118.  
  119.         /* let others know... */
  120.         cryptflag = TRUE;
  121.  
  122.         /* and set up the key to be used! */
  123.         /* de-encrypt it */
  124.         crypt((char *)NULL, 0);
  125.         crypt(curbp->b_key, strlen(curbp->b_key));
  126.  
  127.         /* re-encrypt it...seeding it to start */
  128.         crypt((char *)NULL, 0);
  129.         crypt(curbp->b_key, strlen(curbp->b_key));
  130.     }
  131.  
  132.     return(TRUE);
  133. }
  134. #endif
  135.  
  136. getfile(fname, lockfl)
  137.  
  138. char fname[];        /* file name to find */
  139. int lockfl;        /* check the file for locks? */
  140.  
  141. {
  142.         register BUFFER *bp;
  143.         register LINE   *lp;
  144.         register int    i;
  145.         register int    s;
  146.         char bname[NBUFN];    /* buffer name to put file */
  147.  
  148.         for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
  149.                 if ((bp->b_flag&BFINVS)==0 && strcmp(bp->b_fname, fname)==0) {
  150.             swbuffer(bp);
  151.                         lp = curwp->w_dotp;
  152.                         i = curwp->w_ntrows/2;
  153.                         while (i-- && lback(lp)!=curbp->b_linep)
  154.                                 lp = lback(lp);
  155.                         curwp->w_linep = lp;
  156.                         curwp->w_flag |= WFMODE|WFHARD;
  157.                         mlwrite("[Old buffer]");
  158.                         return (TRUE);
  159.                 }
  160.         }
  161.         makename(bname, fname);                 /* New buffer name.     */
  162.         while ((bp=bfind(bname, FALSE, 0)) != NULL) {
  163.                 s = mlreply("Buffer name: ", bname, NBUFN);
  164.                 if (s == ABORT)                 /* ^G to just quit      */
  165.                         return (s);
  166.                 if (s == FALSE) {               /* CR to clobber it     */
  167.                         makename(bname, fname);
  168.                         break;
  169.                 }
  170.         }
  171.         if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL) {
  172.                 mlwrite("Cannot create buffer");
  173.                 return (FALSE);
  174.         }
  175.         if (--curbp->b_nwnd == 0) {             /* Undisplay.           */
  176.                 curbp->b_dotp = curwp->w_dotp;
  177.                 curbp->b_doto = curwp->w_doto;
  178.                 curbp->b_markp = curwp->w_markp;
  179.                 curbp->b_marko = curwp->w_marko;
  180.         }
  181.         curbp = bp;                             /* Switch to it.        */
  182.         curwp->w_bufp = bp;
  183.         curbp->b_nwnd++;
  184.         return(readin(fname, lockfl));          /* Read it in.          */
  185. }
  186.  
  187. /*
  188.  * Read file "fname" into the current
  189.  * buffer, blowing away any text found there. Called
  190.  * by both the read and find commands. Return the final
  191.  * status of the read. Also called by the mainline,
  192.  * to read in a file specified on the command line as
  193.  * an argument. If the filename ends in a ".c", CMODE is
  194.  * set for the current buffer.
  195.  */
  196. readin(fname, lockfl)
  197.  
  198. char    fname[];    /* name of file to read */
  199. int    lockfl;        /* check for file locks? */
  200.  
  201. {
  202.         register LINE   *lp1;
  203.         register LINE   *lp2;
  204.         register int    i;
  205.         register WINDOW *wp;
  206.         register BUFFER *bp;
  207.         register int    s;
  208.         register int    nbytes;
  209.         register int    nline;
  210.     register char    *sptr;        /* pointer into filename string */
  211.     int        lflag;        /* any lines longer than allowed? */
  212.         char            line[NLINE];
  213.  
  214. #if    FILOCK
  215.     if (lockfl && lockchk(fname) == ABORT)
  216.         return(ABORT);
  217. #endif
  218. #if    CRYPT
  219.     s = resetkey();
  220.     if (s != TRUE)
  221.         return(s);
  222. #endif
  223.         bp = curbp;                             /* Cheap.               */
  224.         if ((s=bclear(bp)) != TRUE)             /* Might be old.        */
  225.                 return (s);
  226.         bp->b_flag &= ~(BFINVS|BFCHG);
  227. #if    ACMODE
  228.     if (strlen(fname) > 1) {        /* check if a 'C' file    */
  229.         sptr = fname + strlen(fname) - 2;
  230.         if (*sptr == '.' &&
  231.            (*(sptr + 1) == 'c' || *(sptr + 1) == 'h'))
  232.             bp->b_mode |= MDCMOD;
  233.     }
  234. #endif
  235.         strcpy(bp->b_fname, fname);
  236.  
  237.     /* turn off ALL keyboard translation in case we get a dos error */
  238.     TTkclose();
  239.  
  240.         if ((s=ffropen(fname)) == FIOERR)       /* Hard file open.      */
  241.                 goto out;
  242.         if (s == FIOFNF) {                      /* File not found.      */
  243.                 mlwrite("[New file]");
  244.                 goto out;
  245.         }
  246.         mlwrite("[Reading file]");
  247.         nline = 0;
  248.     lflag = FALSE;
  249.         while ((s=ffgetline(line, NLINE)) == FIOSUC || s == FIOLNG
  250.             || s == FIOFUN) {
  251.         if (s == FIOLNG) {
  252.             lflag = TRUE;
  253.             --nline;
  254.         }
  255.                 nbytes = strlen(line);
  256.                 if ((lp1=lalloc(nbytes)) == NULL) {
  257.                         s = FIOERR;             /* Keep message on the  */
  258.                         break;                  /* display.             */
  259.                 }
  260.                 lp2 = lback(curbp->b_linep);
  261.                 lp2->l_fp = lp1;
  262.                 lp1->l_fp = curbp->b_linep;
  263.                 lp1->l_bp = lp2;
  264.                 curbp->b_linep->l_bp = lp1;
  265.                 for (i=0; i<nbytes; ++i)
  266.                         lputc(lp1, i, line[i]);
  267.                 ++nline;
  268.                 if (s == FIOFUN)
  269.                     break;
  270.         }
  271.         ffclose();                              /* Ignore errors.       */
  272.     strcpy(line, "[");
  273.     if (lflag)
  274.         strcat(line, "Long lines wrapped, ");
  275.     if (s == FIOFUN)
  276.         strcat(line, "Funny line at EOF, ");
  277.         if (s == FIOEOF || s == FIOFUN) {        /* Don't zap message!   */
  278.         sprintf(&line[strlen(line)], "Read %d line", nline);
  279.                 if (nline > 1)
  280.             strcat(line, "s");
  281.         strcat(line, "]");
  282.         }
  283.     if (s != FIOERR)
  284.         mlwrite(line);
  285.  
  286. out:
  287.     TTkopen();    /* open the keyboard again */
  288.         for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  289.                 if (wp->w_bufp == curbp) {
  290.                         wp->w_linep = lforw(curbp->b_linep);
  291.                         wp->w_dotp  = lforw(curbp->b_linep);
  292.                         wp->w_doto  = 0;
  293.                         wp->w_markp = NULL;
  294.                         wp->w_marko = 0;
  295.                         wp->w_flag |= WFMODE|WFHARD;
  296.                 }
  297.         }
  298.         if (s == FIOERR || s == FIOFNF)        /* False if error.      */
  299.                 return(FALSE);
  300.         return (TRUE);
  301. }
  302.  
  303. /*
  304.  * Take a file name, and from it
  305.  * fabricate a buffer name. This routine knows
  306.  * about the syntax of file names on the target system.
  307.  * I suppose that this information could be put in
  308.  * a better place than a line of code.
  309.  */
  310. makename(bname, fname)
  311. char    bname[];
  312. char    fname[];
  313. {
  314.         register char   *cp1;
  315.         register char   *cp2;
  316.  
  317.         cp1 = &fname[0];
  318.         while (*cp1 != 0)
  319.                 ++cp1;
  320.  
  321. #if     AMIGA
  322.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='/')
  323.                 --cp1;
  324. #endif
  325. #if     VMS
  326.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']')
  327.                 --cp1;
  328. #endif
  329. #if     CPM
  330.         while (cp1!=&fname[0] && cp1[-1]!=':')
  331.                 --cp1;
  332. #endif
  333. #if     MSDOS
  334.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\'&&cp1[-1]!='/')
  335.                 --cp1;
  336. #endif
  337. #if     ST520
  338.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\')
  339.                 --cp1;
  340. #endif
  341. #if     FINDER
  342.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\'&&cp1[-1]!='/')
  343.                 --cp1;
  344. #endif
  345. #if     V7 | USG | BSD
  346.         while (cp1!=&fname[0] && cp1[-1]!='/')
  347.                 --cp1;
  348. #endif
  349.         cp2 = &bname[0];
  350.         while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';')
  351.                 *cp2++ = *cp1++;
  352.         *cp2 = 0;
  353. }
  354.  
  355. /*
  356.  * Ask for a file name, and write the
  357.  * contents of the current buffer to that file.
  358.  * Update the remembered file name and clear the
  359.  * buffer changed flag. This handling of file names
  360.  * is different from the earlier versions, and
  361.  * is more compatable with Gosling EMACS than
  362.  * with ITS EMACS. Bound to "C-X C-W".
  363.  */
  364. filewrite(f, n)
  365. {
  366.         register WINDOW *wp;
  367.         register int    s;
  368.         char            fname[NFILEN];
  369.  
  370.     if (restflag)        /* don't allow this command if restricted */
  371.         return(resterr());
  372.         if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE)
  373.                 return (s);
  374.         if ((s=writeout(fname)) == TRUE) {
  375.                 strcpy(curbp->b_fname, fname);
  376.                 curbp->b_flag &= ~BFCHG;
  377.                 wp = wheadp;                    /* Update mode lines.   */
  378.                 while (wp != NULL) {
  379.                         if (wp->w_bufp == curbp)
  380.                                 wp->w_flag |= WFMODE;
  381.                         wp = wp->w_wndp;
  382.                 }
  383.         }
  384.         return (s);
  385. }
  386.  
  387. /*
  388.  * Save the contents of the current
  389.  * buffer in its associatd file. No nothing
  390.  * if nothing has changed (this may be a bug, not a
  391.  * feature). Error if there is no remembered file
  392.  * name for the buffer. Bound to "C-X C-S". May
  393.  * get called by "C-Z".
  394.  */
  395. filesave(f, n)
  396. {
  397.         register WINDOW *wp;
  398.         register int    s;
  399.  
  400.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  401.         return(rdonly());    /* we are in read only mode    */
  402.         if ((curbp->b_flag&BFCHG) == 0)         /* Return, no changes.  */
  403.                 return (TRUE);
  404.         if (curbp->b_fname[0] == 0) {           /* Must have a name.    */
  405.                 mlwrite("No file name");
  406.                 return (FALSE);
  407.         }
  408.         if ((s=writeout(curbp->b_fname)) == TRUE) {
  409.                 curbp->b_flag &= ~BFCHG;
  410.                 wp = wheadp;                    /* Update mode lines.   */
  411.                 while (wp != NULL) {
  412.                         if (wp->w_bufp == curbp)
  413.                                 wp->w_flag |= WFMODE;
  414.                         wp = wp->w_wndp;
  415.                 }
  416.         }
  417.         return (s);
  418. }
  419.  
  420. /*
  421.  * This function performs the details of file
  422.  * writing. Uses the file management routines in the
  423.  * "fileio.c" package. The number of lines written is
  424.  * displayed. Sadly, it looks inside a LINE; provide
  425.  * a macro for this. Most of the grief is error
  426.  * checking of some sort.
  427.  */
  428. writeout(fn)
  429. char    *fn;
  430. {
  431.         register int    s;
  432.         register LINE   *lp;
  433.         register int    nline;
  434.  
  435. #if    CRYPT
  436.     s = resetkey();
  437.     if (s != TRUE)
  438.         return(s);
  439. #endif
  440.     /* turn off ALL keyboard translation in case we get a dos error */
  441.     TTkclose();
  442.  
  443.         if ((s=ffwopen(fn)) != FIOSUC) {        /* Open writes message. */
  444.         TTkopen();
  445.                 return (FALSE);
  446.         }
  447.     mlwrite("[Writing..]");            /* tell us were writing */
  448.         lp = lforw(curbp->b_linep);             /* First line.          */
  449.         nline = 0;                              /* Number of lines.     */
  450.         while (lp != curbp->b_linep) {
  451.                 if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
  452.                         break;
  453.                 ++nline;
  454.                 lp = lforw(lp);
  455.         }
  456.         if (s == FIOSUC) {                      /* No write error.      */
  457.                 s = ffclose();
  458.                 if (s == FIOSUC) {              /* No close error.      */
  459.                         if (nline == 1)
  460.                                 mlwrite("[Wrote 1 line]");
  461.                         else
  462.                                 mlwrite("[Wrote %d lines]", nline);
  463.                 }
  464.         } else                                  /* Ignore close error   */
  465.                 ffclose();                      /* if a write error.    */
  466.     TTkopen();
  467.         if (s != FIOSUC)                        /* Some sort of error.  */
  468.                 return (FALSE);
  469.         return (TRUE);
  470. }
  471.  
  472. /*
  473.  * The command allows the user
  474.  * to modify the file name associated with
  475.  * the current buffer. It is like the "f" command
  476.  * in UNIX "ed". The operation is simple; just zap
  477.  * the name in the BUFFER structure, and mark the windows
  478.  * as needing an update. You can type a blank line at the
  479.  * prompt if you wish.
  480.  */
  481. filename(f, n)
  482. {
  483.         register WINDOW *wp;
  484.         register int    s;
  485.         char            fname[NFILEN];
  486.  
  487.     if (restflag)        /* don't allow this command if restricted */
  488.         return(resterr());
  489.         if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT)
  490.                 return (s);
  491.         if (s == FALSE)
  492.                 strcpy(curbp->b_fname, "");
  493.         else
  494.                 strcpy(curbp->b_fname, fname);
  495.         wp = wheadp;                            /* Update mode lines.   */
  496.         while (wp != NULL) {
  497.                 if (wp->w_bufp == curbp)
  498.                         wp->w_flag |= WFMODE;
  499.                 wp = wp->w_wndp;
  500.         }
  501.     curbp->b_mode &= ~MDVIEW;    /* no longer read only mode */
  502.         return (TRUE);
  503. }
  504.  
  505. /*
  506.  * Insert file "fname" into the current
  507.  * buffer, Called by insert file command. Return the final
  508.  * status of the read.
  509.  */
  510. ifile(fname)
  511. char    fname[];
  512. {
  513.         register LINE   *lp0;
  514.         register LINE   *lp1;
  515.         register LINE   *lp2;
  516.         register int    i;
  517.         register BUFFER *bp;
  518.         register int    s;
  519.         register int    nbytes;
  520.         register int    nline;
  521.     int        lflag;        /* any lines longer than allowed? */
  522.         char            line[NLINE];
  523.  
  524.         bp = curbp;                             /* Cheap.               */
  525.         bp->b_flag |= BFCHG;            /* we have changed    */
  526.     bp->b_flag &= ~BFINVS;            /* and are not temporary*/
  527.         if ((s=ffropen(fname)) == FIOERR)       /* Hard file open.      */
  528.                 goto out;
  529.         if (s == FIOFNF) {                      /* File not found.      */
  530.                 mlwrite("[No such file]");
  531.         return(FALSE);
  532.         }
  533.         mlwrite("[Inserting file]");
  534.  
  535. #if    CRYPT
  536.     s = resetkey();
  537.     if (s != TRUE)
  538.         return(s);
  539. #endif
  540.     /* back up a line and save the mark here */
  541.     curwp->w_dotp = lback(curwp->w_dotp);
  542.     curwp->w_doto = 0;
  543.     curwp->w_markp = curwp->w_dotp;
  544.     curwp->w_marko = 0;
  545.  
  546.         nline = 0;
  547.     lflag = FALSE;
  548.         while ((s=ffgetline(line, NLINE)) == FIOSUC || s == FIOLNG
  549.             || s == FIOFUN) {
  550.         if (s == FIOLNG) {
  551.             lflag = TRUE;
  552.             --nline;
  553.         }
  554.                 nbytes = strlen(line);
  555.                 if ((lp1=lalloc(nbytes)) == NULL) {
  556.                         s = FIOERR;             /* Keep message on the  */
  557.                         break;                  /* display.             */
  558.                 }
  559.         lp0 = curwp->w_dotp;    /* line previous to insert */
  560.         lp2 = lp0->l_fp;    /* line after insert */
  561.  
  562.         /* re-link new line between lp0 and lp2 */
  563.         lp2->l_bp = lp1;
  564.         lp0->l_fp = lp1;
  565.         lp1->l_bp = lp0;
  566.         lp1->l_fp = lp2;
  567.  
  568.         /* and advance and write out the current line */
  569.         curwp->w_dotp = lp1;
  570.                 for (i=0; i<nbytes; ++i)
  571.                         lputc(lp1, i, line[i]);
  572.                 ++nline;
  573.                 if (s == FIOFUN)
  574.                     break;
  575.         }
  576.         ffclose();                              /* Ignore errors.       */
  577.     curwp->w_markp = lforw(curwp->w_markp);
  578.     strcpy(line, "[");
  579.     if (lflag)
  580.         strcat(line, "Long lines wrapped, ");
  581.     if (s == FIOFUN)
  582.         strcat(line, "Funny line at EOF, ");
  583.         if (s == FIOEOF || s == FIOFUN) {        /* Don't zap message!   */
  584.         sprintf(&line[strlen(line)], "Inserted %d line", nline);
  585.                 if (nline > 1)
  586.             strcat(line, "s");
  587.         strcat(line, "]");
  588.         }
  589.     if (s != FIOERR)
  590.         mlwrite(line);
  591. out:
  592.     /* advance to the next line and mark the window for changes */
  593.     curwp->w_dotp = lforw(curwp->w_dotp);
  594.     curwp->w_flag |= WFHARD | WFMODE;
  595.  
  596.     /* copy window parameters back to the buffer structure */
  597.     curbp->b_dotp = curwp->w_dotp;
  598.     curbp->b_doto = curwp->w_doto;
  599.     curbp->b_markp = curwp->w_markp;
  600.     curbp->b_marko = curwp->w_marko;
  601.  
  602.         if (s == FIOERR)                        /* False if error.      */
  603.                 return (FALSE);
  604.         return (TRUE);
  605. }
  606.